from typing import List, Dict, Tuple
import numpy as np
from .game_state import FactorDevelopment, GameWorld

class FactorController:
    """因子行为控制器"""
    
    def __init__(self, game_world: GameWorld):
        self.game_world = game_world
        self.decision_weights = self._init_decision_weights()
    
    def _init_decision_weights(self) -> Dict:
        """初始化决策权重"""
        return {
            "explore": 0.3,      # 探索权重
            "train": 0.25,       # 训练权重  
            "social": 0.15,      # 社交权重
            "event": 0.2,        # 事件参与权重
            "rest": 0.1          # 休息权重
        }
    
    def make_decision(self, factor: FactorDevelopment, current_time: int) -> str:
        """为因子制定决策"""
        # 基于因子类型和当前状态做出决策
        if factor.factor_type.name == "MYDEI":
            return self._aggressive_decision(factor, current_time)
        elif factor.factor_type.name == "HYACINE":
            return self._support_decision(factor, current_time)
        elif factor.factor_type.name == "TRIBBIE":
            return self._mobile_decision(factor, current_time)
        else:
            return self._balanced_decision(factor, current_time)
    
    def _aggressive_decision(self, factor: FactorDevelopment, current_time: int) -> str:
        """攻击型决策逻辑"""
        nearby_events = self._find_nearby_events(factor.current_location, 20.0)
        
        if nearby_events and factor.level >= 8:
            return f"participate_event:{nearby_events[0].name}"
        elif factor.level < 5:
            return "train_combat"
        else:
            return "explore_dangerous"
    
    def _support_decision(self, factor: FactorDevelopment, current_time: int) -> str:
        """支援型决策逻辑"""
        # 寻找需要帮助的队友
        weak_allies = self._find_weak_allies(factor.current_location)
        
        if weak_allies:
            return f"support_ally:{weak_allies[0].name}"
        elif factor.attributes['healing'] < 50:
            return "train_healing"
        else:
            return "explore_safe"
    
    def _mobile_decision(self, factor: FactorDevelopment, current_time: int) -> str:
        """机动型决策逻辑"""
        unexplored_areas = self._find_unexplored_areas(factor.current_location)
        
        if unexplored_areas and factor.attributes['mobility'] > 30:
            return f"move_to:{unexplored_areas[0]}"
        else:
            return "train_mobility"
    
    def _balanced_decision(self, factor: FactorDevelopment, current_time: int) -> str:
        """平衡型决策逻辑"""
        decisions = ["train_balanced", "explore_balanced", "socialize"]
        weights = [0.4, 0.4, 0.2]
        
        return np.random.choice(decisions, p=weights)
    
    def _find_nearby_events(self, location: Tuple[float, float], radius: float) -> List:
        """寻找附近事件"""
        nearby = []
        for event in self.game_world.events + list(self.game_world.titan_events.values()):
            if (not event.completed and event.active and 
                self._calculate_distance(location, event.location) <= radius):
                nearby.append(event)
        return nearby
    
    def _find_weak_allies(self, location: Tuple[float, float]) -> List[FactorDevelopment]:
        """寻找需要帮助的队友"""
        weak_allies = []
        for ally in self.game_world.factors:
            if (ally.is_alive and ally != self and
                self._calculate_distance(location, ally.current_location) <= 15.0 and
                ally.attributes['health'] < ally.attributes['health'] * 0.5):
                weak_allies.append(ally)
        return weak_allies
    
    def _find_unexplored_areas(self, location: Tuple[float, float]) -> List[Tuple[float, float]]:
        """寻找未探索区域"""
        # 简单实现：返回随机方向
        directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
        unexplored = []
        
        for dx, dy in directions:
            new_x = max(0, min(100, location[0] + dx * 20))
            new_y = max(0, min(100, location[1] + dy * 20))
            unexplored.append((new_x, new_y))
            
        return unexplored
    
    def _calculate_distance(self, pos1: Tuple[float, float], pos2: Tuple[float, float]) -> float:
        """计算两点距离"""
        return np.sqrt((pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2)
    
    def execute_decision(self, factor: FactorDevelopment, decision: str):
        """执行决策"""
        if decision.startswith("move_to"):
            # 解析移动目标
            target_str = decision.split(":")[1]
            target = eval(target_str)  # 简单实现，实际应该更安全
            factor.move_to(target)
            
        elif decision.startswith("participate_event"):
            event_name = decision.split(":")[1]
            # 参与事件逻辑...
            
        elif decision.startswith("train"):
            training_type = decision.split("_")[1]
            self._train_attribute(factor, training_type)
            
        elif decision == "explore_dangerous":
            # 探索危险区域
            dangerous_spot = (np.random.uniform(70, 100), np.random.uniform(70, 100))
            factor.move_to(dangerous_spot)
            
        elif decision == "explore_safe":
            # 探索安全区域  
            safe_spot = (np.random.uniform(0, 30), np.random.uniform(0, 30))
            factor.move_to(safe_spot)
    
    def _train_attribute(self, factor: FactorDevelopment, attribute: str):
        """训练属性"""
        if attribute in factor.attributes:
            improvement = np.random.uniform(1.0, 3.0)
            factor.attributes[attribute] += improvement
            factor.experience += improvement * 10
            
            if factor.experience >= factor.level * 100:
                factor.level_up()